<template>
  <div class="text-editor">
    <div class="editor-toolbar flexbetween">
      <div class="flex flexwrap">
        <EmojiPop ref="emoji" @chooseEmoji='chooseEmoji' v-if="!hideEmoji" class="emobox"/>
        <span class="toolbar-tag" v-for="(tag, index) in toolTags" :key="index" @click="addEditorToHtml(tag)">
          <template v-if="tag == '随机表情'">
            <el-tooltip placement="top">
              <div slot="content">
                每个群发对象的消息，将在以下表情中随机，降低消息重复性带来的风险<br/>
                <img src="@/assets/images/random_emoji_img.png" alt="" class="toolimg mt-3">
              </div>
              <span> {{ tag.text }} </span>
            </el-tooltip>
          </template>
          <span v-else> {{ tag.text }} </span>
        </span>
      </div>
      <div v-if="havecopy" class="c_primary commhover" @click="handleCopy">复制</div>
    </div>
    <quill-editor
      class="quill-editor-wrap"
      ref="myQuillEditor"
      v-model="noticeContent"
      :content="content"
      :options="{...editorOption, ...options}"
      placeholder="请输入"
      @change="onEditorChange($event)"
    />
    <div class="editor-footer" v-if="!hideFooter">
      <uploadImage v-model="form.carouselPics" :limit='20' :isShowTip='false'/>
      <!--      <el-upload-->
      <!--        class="upload-img"-->
      <!--        v-if="!hideImageBtn"-->
      <!--        multiple-->
      <!--        action=""-->
      <!--        :limit="1"-->
      <!--        :on-exceed="handleExceed"-->

      <!--        :file-list="fileList">-->
      <!--        <el-tooltip content="不大于10M" placement="top" effect="light">-->
      <!--          <el-button size="small" plain icon="el-icon-plus">图片</el-button>-->
      <!--        </el-tooltip>-->
      <!--      </el-upload>-->
      <el-upload
        v-if="!hideVideoBtn"
        class="upload-video"
        multiple
        action=""
        :limit="1"
        :on-exceed="handleExceed"
        :file-list="fileList">
        <el-tooltip content="不大于10M" placement="top" effect="light">
          <el-button size="small" plain icon="el-icon-plus">视频</el-button>
        </el-tooltip>
      </el-upload>
      <div v-if="!hideImageText">
        <el-button size="small" plain icon="el-icon-plus" @click="showImageText = true">图文</el-button>
      </div>
      <div v-if="!hideMini">
        <el-button size="small" plain icon="el-icon-plus" @click="showAddMini = true">小程序</el-button>
      </div>
      <slot/>
      <span class="content-count" v-if="!hideMini || !hideVideoBtn || !hideImageText">（0/9）</span>
      <div class="fileContent">
        <!--      图片-->
        <div class="item images" v-for="(item,index) in imagesList"><img :src="item"/>
          <div class="topContent">
            <i class="el-icon-view" @click="handerView(item)"></i>
            <i class="el-icon-delete"></i>
          </div>
        </div>
        <!--      视频-->
        <div class="item video"><img src="@/assets/images/profile.jpg"/>
          <div class="topContent">
            <i class="el-icon-view"></i>
            <i class="el-icon-delete"></i>
          </div>
        </div>
        <!--      链接或者小程序-->
        <div class="item linkOrWX">
          <div class="title">百度</div>
          <div class="content-big">
            <div class="content">这是百度的说明</div>
            <img src="@/assets/images/profile.jpg"/>
          </div>

          <div class="topContent">
            <i class="el-icon-edit"></i>
            <i class="el-icon-delete"></i>
          </div>
        </div>
        <div class="item linkOrWX">
          <div class="title">
            <svg-icon icon-class="wxChat" style="font-size: 14px; color: #576b95; margin-right: 5px"/>
            小程序
          </div>
          <div class="content-big">
            <div class="content">这是小程序</div>
            <img src="@/assets/images/profile.jpg"/>
          </div>

          <div class="topContent">
            <i class="el-icon-edit"></i>
            <i class="el-icon-delete"></i>
          </div>
        </div>

      </div>
    </div>
    <ImageTextDialog :visible="showImageText" @handCloseDialog="onHandCloseImageTextDialog"/>
    <AddMiniDialog :visible="showAddMini" @handCloseDialog="onHandCloseAddMiniDialog"/>
    <el-dialog
      :visible.sync="dialogVisible"
      title="预览"
      width="800"
      append-to-body
    >
      <img
        :src="dialogImageUrl"
        style="display: block; max-width: 100%; margin: 0 auto"
      />
    </el-dialog>
  </div>
</template>
<script>
import {quillEditor, Quill} from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import EmojiPop from '@/components/EmojiPop';
import ImageTextDialog from './imageTextDialog.vue'
import AddMiniDialog from './addMiniDialog.vue';
import uploadImage from './uploadImage.vue'
export default {
  data() {
    return {
      content: '',
      showImageText: false,
      dialogVisible: false,
      showAddMini: false,
      editorOption: {
        modules: {
          // 隐藏工具栏
          toolbar: false,
        },
        placeholder: '请输入欢迎语'
      },
      fileList: [],
      imagesList:[],
      form: {
        carouselPics: [],
      },
      noticeContent: null,
      fiterNoticeContent: null,
      dialogImageUrl:null,//图片链接
    }
  },
  components: {
    quillEditor,
    EmojiPop,
    ImageTextDialog,
    AddMiniDialog,
    uploadImage,
  },
  props: {
    options: {
      type: Object,
      default: {}
    },
    hideFooter: {
      type: Boolean,
      default: false
    },
    toolTags: {
      type: Array,
      default: [],
    },
    hideEmoji: {
      type: Boolean,
      default: false
    },
    hideImageBtn: {
      type: Boolean,
      default: false
    },
    hideVideoBtn: {
      type: Boolean,
      default: false
    },
    hideImageText: {
      type: Boolean,
      default: false
    },
    hideMini: {
      type: Boolean,
      default: false
    },
    havecopy: { //是否显示复制按钮
      type: Boolean,
      default: false
    }
  },
  watch: {
    'noticeContent'(val) {
      this.$nextTick(() => {
        this.setCursorToEnd();
      })
      this.fiterContent(val);
    },
    'form.carouselPics'(val) {
      console.log('投票组件', val);
      if (val.indexOf(",") > -1) {
        this.imagesList=val.split(",");
      }else {
        this.imagesList.push(val);
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.myQuillEditor.quill.focus();
    });
    this.fiterContent(this.noticeContent);
  },
  methods: {
    handerView(item){
      this.dialogImageUrl=item;
      this.dialogVisible=true;
    },
    fiterContent(html) {
      let htmlText = html;
      if (htmlText) {
        const reg = /\<span class="edit-tag">.*?<i class="el-icon-close"><\/i>\<\/span>/g;
        const prefix = '<span class="edit-tag">'
        const end = '<i class="el-icon-close"></i></span>'
        if (document.querySelectorAll(".edit-tag .el-icon-close").length > 0) {
          console.log('htmlText', htmlText);
          htmlText.match(reg).forEach(item => {
            const text = `##${item.replace(prefix, '').replace(end, '').trim()}##`
            htmlText = htmlText.replace(item, text)
          })
        }


        //  nickname gender adddate mobile
        htmlText = htmlText.replace(/(.*)<\/p>/g, '$1')
        htmlText = htmlText.replaceAll('</p>', '\n');
        htmlText = htmlText.replaceAll(/<.*?>/g, '');
        for (let i = 0; i < this.toolTags.length; i++) {
          htmlText = htmlText.replaceAll(`##${this.toolTags[i].text.trim()}##`, `##${this.toolTags[i].label.trim()}##`);
        }
        this.fiterNoticeContent = htmlText;
        console.log('this.fiterNoticeContent', this.fiterNoticeContent);
      }
    }
    ,
    setCursorToEnd() {
      // 获取quill实例
      const quill = this.$refs.myQuillEditor.quill;
      // 设置光标位置在最后
      const length = quill.getLength();
      console.log('length光标长度', length);
      this.$nextTick(() => {
        quill.setSelection(length + 1, length + 1);
      })

    }
    ,
    handleExceed(e) {

    }
    ,
    onEditorBlur(quill) {
      console.log('editor blur!', quill)
    }
    ,
    onEditorFocus(quill) {
      console.log('editor focus!', quill)
    }
    ,
    onEditorReady(quill) {
      console.log('editor ready!', quill)
    }
    ,
    onEditorChange({quill, html, text}) {
      console.log('editor change!', quill, html, text)
      this.content = html
      this.transValue()
    }
    ,
    //选择表情包
    chooseEmoji(icon) {
      const quill = this.$refs.myQuillEditor.quill
      // 获取光标所在位置
      const length = quill.selection.savedRange.index
      // 插入
      quill.insertEmbed(length, 'IconEmbed', {src: icon.icon, title: icon.name}) // 'video'即为上面定义的blotName
      // 调整光标到最后
      quill.setSelection(length + 1)
      // 隐藏表情浮窗
      this.$refs.emoji.showemoji = false
    }
    ,
    addEditorToHtml(tag) {
      const quill = this.$refs.myQuillEditor.quill;
      // 获取光标所在位置
      const length = quill.selection.savedRange.index;
      // quill.insertEmbed(length, 'StockEmbed', tag) // 'video'即为上面定义的blotName
      quill.insertEmbed(length, 'StockEmbed', `<span class="edit-tag">${tag.text}<i class="el-icon-close"></i></span>`) // 'video'即为上面定义的blotName
      this.$nextTick(() => {
        const length = quill.selection.savedRange.index;
        // 调整光标到最后
        quill.setSelection(length + 1);
      })
    }
    ,
    onHandCloseImageTextDialog() {
      this.showImageText = false
    }
    ,
    onHandCloseAddMiniDialog() {
      this.showAddMini = false
    }
    ,

    replacePTagsWithNewline(htmlString) {
      // 使用正则表达式匹配所有的<p>标签，并将其替换为换行符
      return htmlString.replace(/<p[^>]*>|<\/p>/gi, function (match) {
        return match === '</p>' ? '\n' : '';
      });
    }
    ,

    loopUntilTextNode(node) {
      console.log('node.childNodes:', node.childNodes)
      for (let i = 0; i < node.childNodes.length; i++) {
        let childNode = node.childNodes[i];
        if (childNode.nodeType === Node.TEXT_NODE && childNode.textContent.trim() !== '') {
          console.log('childNode', childNode, childNode.parentNode)
          return childNode;  //childNode为他的文本内容  childNode.parentNode是他的父节点
        } else {
          let result = this.loopUntilTextNode(childNode);
          if (result) return result;
        }
      }
      return null;
    }
    ,

    // 值转换
    transValue() {

      // let result = this.replacePTagsWithNewline(this.content)
      let result = this.content
      // result = result.replaceAll('<span class="embed-tag" contenteditable="true">﻿<span contenteditable="false"><span class="edit-tag">','{{').replaceAll('</span></span>﻿</span>','}}')
      console.log('result：', result)
      let node = new DOMParser().parseFromString(result, 'text/html').body
      console.log('node：', this.loopUntilTextNode(node))
      // let tagElements = node.getElementsByClassName('embed-tag')
      // console.log('tagElements:',tagElements.length)
      // if (tagElements.length > 0) {
      //   for (const element of tagElements) {
      //     console.log('hhhhhhhhhhh:',element.textContent);
      //   }
      //   // tagElements.forEach(element => {
      //   //   console.log('hhhhhhhhhhh-',element)
      //   // });
      // }
      // let node = new DOMParser().parseFromString(this.content,'text/html').body
      // console.log('node:', node)

      // let pElements = node.getElementsByTagName('p');
      // console.log('pElements',pElements.length)
      // let transText = ''
      // if (pElements.length > 0) {
      //   // // 获取第一个p元素的文本内容
      //   var text = pElements[0].textContent;
      //   console.log('text:', text)
      //   // // 将内容替换为换行符
      //   // transText = transText + text.replace(/[\w\s]+/g, '\n');
      // }
      // console.log('transText:', transText)
    }
    ,

    handleCopy() {
      // 获取所有的p元素
      let htmlText = this.fiterNoticeContent;
      if (htmlText) {
        this.copy(this.fiterNoticeContent.trim())
      } else {
        this.copy('')
      }

    }
  },
}

const BlotsEmbed = Quill.import('blots/embed')

class StockEmbed extends BlotsEmbed {
  constructor(scroll, domNode) {
    super(scroll, domNode);
    // 绑定删除事件
    console.log('this.domNode', this.domNode)
    if (this.domNode.querySelector(".el-icon-close")) {
      this.domNode.querySelector(".el-icon-close").addEventListener('click', () => {
        console.log('删除了')
        this.remove();
      });
    }

  }

  static create(value) {
    const node = super.create(value);
    node.setAttribute('contenteditable', 'true');
    // node.setAttribute('style', 'display: flex;align-items: center;height:26px;');
    //   设置自定义html
    node.innerHTML = value;
    console.log('node:', node.querySelector('i'))
    let i_node = node.querySelector('i')
    if (i_node) {
      i_node.onclick = function () {
        console.log('点击了')
      }
    }
    return node;
  }

  // 去除字符串模板(``)语法中存在的空格
  static transformValue(value) {
    let handleArr = value.split('\n');
    handleArr = handleArr.map((e) => e.replace(/^[\s]+/, '').replace(/[\s]+$/, ''));
    return handleArr.join('');
  }

  // 返回节点自身的value值 用于撤销操作
  static value(node) {
    return node.innerHTML;
  }
}

class EmojiEmbed extends BlotsEmbed {
  static create(value) {
    const node = super.create(value);
    node.setAttribute('title', value.title);
    node.setAttribute('src', value.src);
    node.setAttribute('style', 'width: 24px;height:24px;');
    return node;
  }

  static value(node) {
    return {
      src: node.getAttribute('src'), // 注意这里和上面的属性和值反过来相对
      title: node.getAttribute('title'),
    }
  }
}

StockEmbed.blotName = 'StockEmbed';
StockEmbed.className = 'embed-tag';
StockEmbed.tagName = 'span';

EmojiEmbed.blotName = 'IconEmbed';
EmojiEmbed.className = 'embed-emoji';
EmojiEmbed.tagName = 'img';

Quill.register(StockEmbed, true);
Quill.register(EmojiEmbed, true);
</script>
<style lang="scss" scoped>
.text-editor {
  width: 100%;
  border: 1px solid #e9e9e9;

  .editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: #fafafa;
    border-bottom: 1px solid #e9e9e9;

    .emobox {
      line-height: 22px;
      margin-top: 3px;
    }

    .toolbar-tag {
      padding: 3px 8px;
      background: #fff;
      cursor: pointer;
      border-radius: 4px;
      color: rgba(0, 0, 0, .65);
      font-size: 12px;
      line-height: 20px;
      border: 1px solid #e9e9e9;
      margin-right: 8px;
    }
  }

  .quill-editor-wrap {
    min-height: 200px;

    ::v-deep .ql-container.ql-snow {
      border: none;
    }

    ::v-deep .ql-editor.ql-blank::before {
      font-style: normal;
    }

    // ::v-deep .ql-editor p {
    //   display: flex;
    //   align-items: center;
    // }
    ::v-deep .edit-tag {
      color: rgba(0, 0, 0, .85);
      background: #eff2fe;
      border-radius: 2px;
      border: 1px solid #d5ddfb;
      margin: 0 3px 3px;
      padding: 2px 7px;
      font-size: 12px;
      padding-right: 3px;
      width: auto;

      .el-icon-close {
        cursor: pointer;
        padding-left: 3px;
      }
    }
  }

  .editor-footer {
    display: flex;
    align-items: center;
    padding: 8px;
    background: #f3f3f3;
    border: 1px solid #e9e9e9;
    gap: 8px;
    flex-wrap: wrap;

    .content-count {
      margin-left: 8px;
      color: rgba(0, 0, 0, .45);
      font-size: 14px;
      line-height: 22px;
    }
  }
}

.toolimg {
  width: 460px
}

.fileContent {
  display: flex;
  flex-wrap: wrap;
  width: 100%;

  .item {
    position: relative;
    overflow: hidden;
    height: 100px;
    margin-bottom: 8px;
    margin-right: 12px;
    background: #fff;
    border-radius: 2px;
    border: 1px solid #e9e9e9;
    padding: 12px;

    &:hover {
      .topContent {
        display: flex;
      }
    }

    &.images, &.video {
      width: 100px;
      height: 100px;

      img {
        width: 100%;
        height: 100%;
      }
    }

    &.linkOrWX {
      width: 230px;
    }

    .topContent {
      position: absolute;
      left: 0px;
      top: 0px;
      background: rgba(0, 0, 0, .65);
      color: #fff;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      display: none;

      i {
        font-size: 16px;
        margin: 0px 10px;
        cursor: pointer;
      }
    }
  }

  .content-big {
    display: flex;
    align-items: center;
    height: 60px;
    line-height: 25px;
    justify-content: space-between;

    .content {
      flex: 1;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    img {
      width: 48px;
      height: 48px;
      background: #c3c8d1;
      border-radius: 4px;
    }
  }
}
::v-deep .el-upload-list {
  display: none !important;
}
</style>
